package com.ly.base.chapter03;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import java.util.stream.Collector;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * 并行流:
 *      多线程处理
 */
public class APParallelDemo {
    public static void main(String[] args) {

        /**
         * 1) 数据量问题：数据量大时才建议用并行流
         * 2) 线程会无限增加吗：跟 cpu 能处理的线程数相关
         * 3) 收尾意义：转不可变集合、StringBuilder 转String
         * 4) 是否线程安全：不会
         * 5) 特性：
         *      是否需要收尾（默认收尾）
         *      是否需要保证顺序（默认保证）
         *      容器是否支持并发（默认不需要支持）
         *
         *      到底选择哪一种容器？
         *          A. Characteristics.CONVURRENT + Characteristics.UNORDERED + 线程安全容器
         *          B. 默认 + 线程不安全容器
         *
         */
        List<Integer> collect = Stream.of(1,2,3,4)
                .parallel()  // 转换为并行流
                .collect(Collector.of(
                        () -> {
                            System.out.printf("%-12s %s%n",simple(),"create");
//                           return new ArrayList<Integer>();
                            return new Vector<Integer>(); // 线程安全容器 --- 保证只创建一次
                        },                                           // 1、如何创建容器
                        (list,x) -> {
                            List<Integer> old = new ArrayList<>(list);
                            list.add(x);
                            System.out.printf("%-12s %s.add(%d)=>%s%n ",simple(),old,x,list);
                        },                                          // 2、如何向容器添加数据
                        (list1,list2) -> {
                            List<Integer> old = new ArrayList<>(list1);
                            list1.addAll(list2);
                            System.out.printf("%-12s %s.add(%s)=>%s%n", simple(), old, list2, list1);
                            return list1;
                        },                                          // 3、如何合并两个容器的数据
                        list -> {
                            System.out.printf("%-12s finish: %s=>%s%n", simple(), list, list);
                            return list;
                        }                                           // 4、收尾
                        // 5、特性：并发、是否需要收尾、是否要保证收集顺序(不写默认：不支持并发、需要收尾、要保证收集顺序)
                        , Collector.Characteristics.IDENTITY_FINISH     //不需要收尾
                        , Collector.Characteristics.UNORDERED                        //不需要保证顺序
                        , Collector.Characteristics.CONCURRENT                       //需要保证并发

                ));


        System.out.println(collect);

    }

    private static String simple() {
        String name = Thread.currentThread().getName();
        int idx = name.indexOf("worker");
        if (idx > 0) {
            return name.substring(idx);
        }
        return name;
    }

}
